bitkeeper revision 1.290 (3f098d9aV-utpH62PCMaflI0ggwCXQ)
authorsos22@labyrinth.cl.cam.ac.uk <sos22@labyrinth.cl.cam.ac.uk>
Mon, 7 Jul 2003 15:11:22 +0000 (15:11 +0000)
committersos22@labyrinth.cl.cam.ac.uk <sos22@labyrinth.cl.cam.ac.uk>
Mon, 7 Jul 2003 15:11:22 +0000 (15:11 +0000)
Use ioctl rather than /proc/xeno/new_dom_data when creating a new
domain.

tools/internal/xi_create.c
xen/include/hypervisor-ifs/dom0_ops.h
xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_core.c

index 138a2d9f482c79ecb3800d29a0e13b3fbf34e95e..7ebf484e66bf4e7da234f7cc00537f6637f1d0fb 100644 (file)
@@ -12,6 +12,9 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <stdlib.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <string.h>
 
 #include "hypervisor_defs.h"
 #include "dom0_ops.h"
@@ -36,46 +39,36 @@ static void PERROR (char *message)
 
 /***********************************************************************/
 
-static dom0_newdomain_t * create_new_domain(long req_mem, char *name)
+static int create_new_domain(long req_mem, char *name)
 {
-    dom0_newdomain_t * dom_data;
     char cmd_path[MAX_PATH];
-    char dom_id_path[MAX_PATH];
-    dom0_op_t dop;
     int cmd_fd;
-    int id_fd;
+    int dom_id;
+    struct dom0_createdomain_args argbuf;
 
     /* open the /proc command interface */
     sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
-    cmd_fd = open(cmd_path, O_WRONLY);
+    cmd_fd = open(cmd_path, O_RDWR);
     if(cmd_fd < 0){
         PERROR ("Could not open PROC_CMD interface");
-        return 0;
+        return -1;
     }
 
-    dop.cmd = DOM0_CREATEDOMAIN;
-    dop.u.newdomain.memory_kb = req_mem;
-    strncpy (dop.u.newdomain.name, name, MAX_DOMAIN_NAME - 1);
-    dop.u.newdomain.name[MAX_DOMAIN_NAME - 1] = 0;
-
-    write(cmd_fd, &dop, sizeof(dom0_op_t));
+    argbuf.kb_mem = req_mem;
+    argbuf.name = name;
+    dom_id = ioctl(cmd_fd, IOCTL_DOM0_CREATEDOMAIN, &argbuf);
+    if (dom_id < 0) {
+      PERROR("creating new domain");
+    }
     close(cmd_fd);
-
-    sprintf(dom_id_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", 
-        PROC_DOM_DATA);
-    while((id_fd = open(dom_id_path, O_RDONLY)) < 0) continue;
-    dom_data = (dom0_newdomain_t *)malloc(sizeof(dom0_newdomain_t));
-    read(id_fd, dom_data, sizeof(dom0_newdomain_t));
-    close(id_fd);
-    
-    return dom_data;
+    return dom_id;
 }    
 
 /***********************************************************************/
 
 int main(int argc, char **argv)
 {
-  dom0_newdomain_t * dom_data;
+  int dom_id;
 
   if (argv[0] != NULL) 
     {
@@ -88,11 +81,13 @@ int main(int argc, char **argv)
       return -1;
     }
 
-  if(!(dom_data = create_new_domain(atol(argv[1]), argv[2]))) 
+  dom_id = create_new_domain(atol(argv[1]), argv[2]);
+
+  if(dom_id < 0)
     {
       return -1;
     }
 
-  fprintf (stdout, "%d\n", dom_data -> domain);
+  fprintf (stdout, "%d\n", dom_id);
   return 0;
 }
index b437acec26f54239a6f06c33ea1eb6df6793454d..67c69008d62adb71cf2295a1d34ff1ff96933cc3 100644 (file)
@@ -24,6 +24,8 @@
 #define MAX_CMD_LEN       256
 #define MAX_DOMAIN_NAME    16
 
+#define IOCTL_DOM0_CREATEDOMAIN _IOC(_IOC_NONE, 'x', 0, 0)
+
 typedef struct dom0_newdomain_st 
 {
     unsigned int domain;    // return parameter
@@ -112,4 +114,12 @@ typedef struct dom0_op_st
 } dom0_op_t;
 #endif
 
+/* Arguments to the CREATEDOMAIN ioctl on /proc/xeno/dom0_cmd.
+   Probably belongs in a Linux include file somewhere... */
+struct dom0_createdomain_args
+{
+  unsigned int kb_mem;
+  const char *name;
+};
+
 #endif
index cacf0351719e01e847eb5d863e6afcebc39bd7a3..28ad53abefa3641f75d1a712db612b37f9ec5315 100644 (file)
@@ -57,14 +57,20 @@ int direct_disc_unmap(unsigned long, unsigned long, int);
 
 static unsigned char readbuf[1204];
 
-static int cmd_read_proc(char *page, char **start, off_t off,
-                         int count, int *eof, void *data)
+static int dom0_cmd_read(struct file *fp, char *buf, size_t count, loff_t *off)
 {
-    strcpy(page, readbuf);
+    int copied, maxlen;
+    if (count > 1024)
+        count = 1024;
+    maxlen = strlen(readbuf);
+    if (count > maxlen)
+      count = maxlen;
+    copied = count - copy_to_user(buf, readbuf, count);
     *readbuf = '\0';
-    *eof = 1;
-    *start = page;
-    return strlen(page);
+    if (copied != count)
+      return -EFAULT;
+    else
+      return copied;
 }
 
 static ssize_t dom_usage_read(struct file * file, char * buff, size_t size, loff_t * off)
@@ -265,13 +271,11 @@ struct file_operations newdom_data_fops = {
     read:    dom_data_read,
 };
 
-static int cmd_write_proc(struct file *file, const char *buffer, 
-                          u_long count, void *data)
+static int dom0_cmd_write(struct file *file, const char *buffer, size_t size,
+                         loff_t *off)
 {
     dom0_op_t op;
     int ret = 0;
-    struct proc_dir_entry * new_dom_id;
-    dom0_newdomain_t * params;
     
     copy_from_user(&op, buffer, sizeof(dom0_op_t));
 
@@ -285,34 +289,18 @@ static int cmd_write_proc(struct file *file, const char *buffer,
         ret = HYPERVISOR_pt_update((void *)op.u.pgupdate.pgt_update_arr,
                                    op.u.pgupdate.num_pgt_updates);
     }
+    else if (op.cmd == DOM0_CREATEDOMAIN)
+    {
+        /* This is now handled through an ioctl interface. Trying to
+          do it this way means the /proc files for the new domain
+          don't get created properly. */
+        ret = -EOPNOTSUPP;
+    }
     else
     {
         ret = HYPERVISOR_dom0_op(&op);
-
-        /* if new domain created, create proc entries */
-        if(op.cmd == DOM0_CREATEDOMAIN) {
-            create_proc_dom_entries(ret);
-
-            params = (dom0_newdomain_t *)kmalloc(sizeof(dom0_newdomain_t),
-                                                 GFP_KERNEL);
-            params->memory_kb = op.u.newdomain.memory_kb;
-            params->pg_head = op.u.newdomain.pg_head;
-            params->num_vifs = op.u.newdomain.num_vifs;
-            params->domain = op.u.newdomain.domain;
-
-            /* now notify user space of the new domain's id */
-            new_dom_id = create_proc_entry("new_dom_data", 0600, xeno_base);
-            if ( new_dom_id != NULL )
-            {
-                new_dom_id->owner      = THIS_MODULE;
-                new_dom_id->nlink      = 1;
-                new_dom_id->proc_fops  = &newdom_data_fops; 
-                new_dom_id->data       = (void *)params; 
-            }
-        }
     }
     
- out:
     return ret;   
 }
 
@@ -384,7 +372,7 @@ static int xeno_domains_show(struct seq_file *s, void *v)
                 di -> u.getdominfo.state,
                 di -> u.getdominfo.hyp_events,
                 di -> u.getdominfo.mcu_advance,
-                di -> u.getdominfo.pg_head,
+                (void *)di -> u.getdominfo.pg_head,
                 di -> u.getdominfo.tot_pages,
                 di -> u.getdominfo.name);
 
@@ -410,9 +398,70 @@ static struct file_operations proc_xeno_domains_operations = {
     release:        seq_release,
 };
 
+static int handle_dom0_cmd_createdomain(unsigned long data)
+{
+  struct dom0_createdomain_args argbuf;
+  int namelen;
+  dom0_op_t op;
+  int ret;
+
+  if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf))) {
+    printk("fault getting argbuf.\n");
+    return -EFAULT;
+  }
+
+  op.cmd = DOM0_CREATEDOMAIN;
+  op.u.newdomain.domain = -666;
+  op.u.newdomain.memory_kb = argbuf.kb_mem;
+  op.u.newdomain.num_vifs = 0; /* Not used anymore, I hope... */
+  namelen = strnlen_user(argbuf.name, MAX_DOMAIN_NAME);
+  if (copy_from_user(op.u.newdomain.name, argbuf.name, namelen + 1)) {
+    printk("Fault getting domain name\n");
+    return -EFAULT;
+  }
+
+  /* Error checking?  The old code deosn't appear to do any, and I
+     can't see where the return values are documented... */
+  ret = HYPERVISOR_dom0_op(&op);
+
+  if (op.u.newdomain.domain == -666) {
+    /* HACK: We use this to detect whether the create actually
+       succeeded, because Xen doesn't appear to want to tell us... */
+
+    /* The only time I've actually got this to happen was when trying
+       to crate a domain with more memory than is actually in the
+       machine, so we guess the error code is ENOMEM. */
+    return -ENOMEM;
+  }
+
+  /* Create proc entries */
+  ret = op.u.newdomain.domain;
+  create_proc_dom_entries(ret);
+
+  return ret;
+}
+
+static int dom0_cmd_ioctl(struct inode *inode, struct file *file,
+                         unsigned int cmd, unsigned long data)
+{
+  printk("dom0_cmd ioctl command %x\n", cmd);
+  switch (cmd) {
+  case IOCTL_DOM0_CREATEDOMAIN:
+    return handle_dom0_cmd_createdomain(data);
+  default:
+    printk("Unknown dom0_cmd ioctl!\n");
+    return -EINVAL;
+  }
+}
+
 /***********************************************************************/
 
 
+static struct file_operations dom0_cmd_file_ops = {
+  read : dom0_cmd_read,
+  write : dom0_cmd_write,
+  ioctl : dom0_cmd_ioctl
+};
 
 static int __init init_module(void)
 {
@@ -422,12 +471,12 @@ static int __init init_module(void)
     /* xeno control interface */
     *readbuf = '\0';
     dom0_cmd_intf = create_proc_entry("dom0_cmd", 0600, xeno_base);
+
     if ( dom0_cmd_intf != NULL )
     {
         dom0_cmd_intf->owner      = THIS_MODULE;
         dom0_cmd_intf->nlink      = 1;
-        dom0_cmd_intf->read_proc  = cmd_read_proc;
-        dom0_cmd_intf->write_proc = cmd_write_proc;
+       dom0_cmd_intf->proc_fops  = &dom0_cmd_file_ops;
     }
 
     /* domain list interface */